#include "StdAfx.h"
#include "Timer.h"

CTimer::CTimer(void)
{
	if (QueryPerformanceFrequency((LARGE_INTEGER *)&m_i64PerformanceFrequency)) 
    { 
		m_bPerfHardware	= TRUE;
		QueryPerformanceCounter((LARGE_INTEGER *)&m_i64LastPerformanceCounter); 
		m_fTimeScale = 1.0f / m_i64PerformanceFrequency;
	} 
    else 
    { 
		m_bPerfHardware	= FALSE;
		m_i64LastPerformanceCounter = timeGetTime(); 
		m_fTimeScale = 0.001f;	
    } 
    m_nSampleCount = 0;
	m_nCurrentFrameRate	= 0;
	m_nFPSFrameCount = 0;
	m_fFPSTimeElapsed = 0.0f;
}

CTimer::~CTimer(void)
{
}

void CTimer::Tick(float fLockFPS)
{
    float fTimeElapsed; 

	if (m_bPerfHardware) 
    {
		QueryPerformanceCounter((LARGE_INTEGER *)&m_i64CurrentPerformanceCounter);
	} 
    else 
    {
		m_i64CurrentPerformanceCounter = timeGetTime();
	} 
	fTimeElapsed = (m_i64CurrentPerformanceCounter - m_i64LastPerformanceCounter) * m_fTimeScale;

    if (fLockFPS > 0.0f)
    {
        while (fTimeElapsed < (1.0f / fLockFPS))
        {
	        if (m_bPerfHardware) 
            {
		        QueryPerformanceCounter((LARGE_INTEGER *)&m_i64CurrentPerformanceCounter);
	        } 
            else 
            {
		        m_i64CurrentPerformanceCounter = timeGetTime();
	        } 
	        fTimeElapsed = (m_i64CurrentPerformanceCounter - m_i64LastPerformanceCounter) * m_fTimeScale;
        } 
    } 

	m_i64LastPerformanceCounter = m_i64CurrentPerformanceCounter;

    if (fabsf(fTimeElapsed - m_fTimeElapsed) < 1.0f)
    {
        memmove(&m_fFrameTimes[1], m_fFrameTimes, (MAX_SAMPLE_COUNT - 1) * sizeof(float));
        m_fFrameTimes[0] = fTimeElapsed;
        if (m_nSampleCount < MAX_SAMPLE_COUNT) m_nSampleCount++;
    } 
	m_nFPSFrameCount++;
	m_fFPSTimeElapsed += fTimeElapsed;
	if (m_fFPSTimeElapsed > 1.0f) 
    {
		m_nCurrentFrameRate	= m_nFPSFrameCount;
		m_nFPSFrameCount = 0;
		m_fFPSTimeElapsed = 0.0f;
	} 
    m_fTimeElapsed = 0.0f;
    for (ULONG i = 0; i < m_nSampleCount; i++) m_fTimeElapsed += m_fFrameTimes[i];
    if (m_nSampleCount > 0) m_fTimeElapsed /= m_nSampleCount;
}

unsigned long CTimer::GetFrameRate(LPTSTR lpszString) const
{
    if (lpszString)
    {
        _itot(m_nCurrentFrameRate, lpszString, 10);
        _tcscat(lpszString, _T(" FPS"));
    } 
    return(m_nCurrentFrameRate);
}

float CTimer::GetTimeElapsed() const
{
    return(m_fTimeElapsed);
}
